package com.ld.shieldsb.common.core.encryptor;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.Base64;

/**
 * 一、什么是异或加密？
 * <p>
 * 异或运算中，如果某个字符（或数值）x 与 一个数值m 进行异或运算得到y，则再用y 与 m 进行异或运算就可以还原为 x ， 因此应用这个原理可以实现数据的加密解密功能。
 * <p>
 * 二、异或运算使用场景？
 * <p>
 * 两个变量的互换（不借助第三个变量）
 * <p>
 * 数据的简单加密解密
 */
public class MainTest {

    public static void main(String[] args) throws Exception {
        MainTest test = new MainTest();
        String text = "website";// 需要加密的字符串
        System.out.println("原文:" + text);
        int key = 20180805;// key

        String jiami = test.encrypt(text, key);// 加密

        System.out.println("密文:" + jiami);

        String jiemi = test.decrypt(jiami, key);// 解密

        System.out.println("原文文:" + jiemi);

        String orJiami = EorEncryptor.encode(text, 12121);
        String orJiemi = EorEncryptor.decode(orJiami, 12121);
        System.out.println("原文:" + orJiami);
        System.out.println("密文:" + orJiemi);

    }

    private int C1 = 520;
    private int C2 = 1314;

    /**
     * 加密函数
     */
    public String encrypt(String S, int Key) {

        ByteBuffer buffer = ByteBuffer.allocate(S.length() * 2);

        for (int i = 0; i < S.length(); i++) {
            // 依次对字符串中各字符进行操作

            char c = (char) ((S.charAt(i)) ^ (Key >> 8));
            System.out.println(i + "c: " + (int) c);
            byte[] b = charToByte(c);

            buffer.put(b);

            Key = (Key >> 8) * C1 + C2; // 产生下一个密钥
        }
        // System.out.println(buffer.);
        buffer.flip();
        // 构建一个byte数组
        byte[] content = new byte[buffer.limit()];
        // 从ByteBuffer中读取数据到byte数组中
        buffer.get(content);

        // 把byte数组的内容写到标准输出
        System.out.println(bytesToHexString(content));

        return new String(Base64.getEncoder().encodeToString(content));

    }

    /**
     * 解密函数
     */

    public String decrypt(String S, int Key) {
        StringBuffer Result = new StringBuffer();
        byte[] content;
        try {
            content = Base64.getDecoder().decode(S.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return "";
        }
        System.out.println("content: " + bytesToHexString(content));
        for (int i = 0; i < content.length / 2; i++) // 依次对字符串中各字符进行操作
        {
            byte[] b = { content[i * 2], content[i * 2 + 1] };
            char c = byteToChar(b);

            System.out.println(i + "c: " + (int) c);
            Result.append((char) (c ^ (Key >> 8))); // 将密钥移位后与字符异或

            Key = (Key >> 8) * C1 + C2; // 产生下一个密钥;
        }
        return Result.toString();
    }

    // char转化为byte：

    public byte[] charToByte(char c) {
        byte[] b = new byte[2];
        b[0] = (byte) ((c & 0xFF00) >> 8);
        b[1] = (byte) (c & 0xFF);
        return b;
    }

    // byte转换为char：
    public char byteToChar(byte[] b) {
        char c = (char) (((b[0] & 0xFF) << 8) | (b[1] & 0xFF));
        return c;
    }

    public String bytesToHexString(byte[] data, int start, int end) {
        StringBuilder sb = new StringBuilder("");
        if (data == null) {
            return "";
        } else {
            end = Math.min(end, data.length);

            for (int index = start; index < end; ++index) {
                int v = data[index] & 255;
                String hv = Integer.toHexString(v);
                if (hv.length() < 2) {
                    sb.append(0);
                }

                sb.append(hv.toLowerCase());
            }

            return sb.toString();
        }
    }

    public String bytesToHexString(byte[] data) {
        return data == null ? "" : bytesToHexString(data, 0, data.length);
    }

}
